//
//  AppDelegate.m
//  WangJingApp
//
//  Created by 魏强 on 16/12/28.
//  Copyright © 2016年 KDTech. All rights reserved.
//

#import "AppDelegate.h"
#import "UIWindow+Extension.h"
#import "FCUUID.h"
#import "SVProgressHUD.h"
#import "SSProxyProtocol.h"
#import "ShadowsocksClient.h"
#import "KDVpnModel.h"
#import "WXApi.h"
#import "WQMqttManager.h"
#import "KDTabBarController.h"
#import "FMDatabase.h"
#import "KDNavigationController.h"
#import "KDsubscribController.h"
#import "KDGetVpnServiceTool.h"
#import "KDStatusResult.h"
#import "KDMessagePushRequestTool.h"
#import "NSObject+MJKeyValue.h"
#import "KDNoticeListResult.h"
#import "KDNoticeListMiddleBaseResult.h"
#import "KDNoticeListBaseResult.h"
#import "KDMessagePushListCellModel.h"
#import "KDDetailSubscribController.h"
#import "KDMoveFavorParam.h"
#import "KDCollectRequestTool.h"
#import "NSString+KD.h"


static ShadowsocksClient *proxy;
@interface AppDelegate ()<WXApiDelegate>{
    NSTimer  *_timer;
    NSTimer  *_timer_message_push;
    KDDetailSubscribController *singleCtrl;
    
}

@end

@implementation AppDelegate

#pragma mark - 生命周期区
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
    [self setupNotificationWith:application];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getVpnModel:) name:@"LoginPageGetVpnModelNoty" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(CloseTimer:) name:@"LogoutNoty" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VPNConectFail:) name:@"VPNConectFailNoty" object:nil];
    application.statusBarHidden = NO;
    

    
    //注册微信
    [WXApi registerApp:@"wxeb46083b36927518"];

    
    //1.创建窗口
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    
    //获取uuid
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(uuidNeed:) name:FCUUIDsOfUserDevicesDidChangeNotification object:nil];
    NSString * uuid = [FCUUID uuidForDevice];
    KDLog(@"%@",uuid);
    //将uuid存储进沙盒
    [[NSUserDefaults standardUserDefaults] setObject:uuid forKey:UUID];
    [[NSUserDefaults standardUserDefaults] synchronize];
    [self.window switchRootViewController];
    [self.window makeKeyAndVisible];
    
    //我加的
    //[self noticeTimeInterval];
    
    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    KDLog(@"%s", __func__);
    [[WQMqttManager sharedWQMqttManager].manager connectToLast];
    KDLog(@"%@",[WQMqttManager sharedWQMqttManager].manager.subscriptions);
    
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application{
    NSHTTPCookie *cookie;
    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (cookie in [storage cookies])
    {
        [storage deleteCookie:cookie];
    }
}
#pragma mark - 微信的代理方法
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    return [WXApi handleOpenURL:url delegate:self];
}

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    return [WXApi handleOpenURL:url delegate:self];
}
#pragma mark - 通知接收区
- (void)uuidNeed:(NSNotification *)noty
{
    //    NSDictionary *dic =  noty.userInfo;
    //    KDLog(@"%@", dic.description);
}
- (void)applicationWillTerminate:(UIApplication *)application {
    [self saveContext];
}

#pragma mark - Core Data stack

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (NSURL *)applicationDocumentsDirectory {
    // The directory the application uses to store the Core Data store file. This code uses a directory named "KD.WangJingApp" in the application's documents directory.
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (NSManagedObjectModel *)managedObjectModel {
    // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"WangJingApp" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    
    // Create the coordinator and store
    
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"WangJingApp.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application's saved data.";
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        // Report any error we got.
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        KDLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    
    return _persistentStoreCoordinator;
}


- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

#pragma mark - Core Data Saving support

- (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        NSError *error = nil;
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            KDLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}
#pragma mark - 远程推送区
- (void)setupNotificationWith:(UIApplication *)application{
        // iOS8
    UIUserNotificationType type = UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound;
    
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
    // 注册通知类型
    [application registerUserNotificationSettings:settings];
    
    // 申请试用通知
    [application registerForRemoteNotifications];
        
    // 1.取出数据
//        NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
    //
    //    if (userInfo) {
    //        static int count = 0;
    //        count++;
    //        UILabel *label = [[UILabel alloc] init];
    //        label.frame = CGRectMake(0, 40, 200, 200);
    //        label.numberOfLines = 0;
    //        label.textColor = [UIColor whiteColor];
    //        label.font = [UIFont systemFontOfSize:11];
    //        label.backgroundColor = [UIColor orangeColor];
    //        label.text = [NSString stringWithFormat:@" %@ \n %d", userInfo, count];
    //        [self.window.rootViewController.view addSubview:label];
    //    }
    
}
/**
 *  获取到用户对应当前应用程序的deviceToken时就会调用
 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    NSString * tokenAsString = [[[deviceToken description]
                                 stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]
                                stringByReplacingOccurrencesOfString:@" " withString:@""];

    KDAccount *account = [KDAccountTool account];
    if (!account) {
        account = [[KDAccount alloc]init];
    }
    account.deviceToken = tokenAsString;
    [KDAccountTool saveAccount:account];
    KDLog(@"%@,\n account.deviceToken:%@", deviceToken,account.deviceToken);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    /*
     如果应用程序在后台 , 只有用户点击了通知之后才会调用
     如果应用程序在前台, 会直接调用该方法
     即便应用程序关闭也可以接收到远程通知
     */
    KDLog(@"%s", __func__);
}
//接收到远程服务器推送过来的内容就会调用
// ios7以后用这个处理后台任务接收到得远程通知
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    /*
     UIBackgroundFetchResultNewData, 成功接收到数据
     UIBackgroundFetchResultNoData, 没有;接收到数据
     UIBackgroundFetchResultFailed 接收失败
     
     */
    KDLog(@"%@",userInfo);
    //    KDLog(@"%@", userInfo);
    NSNumber *type = userInfo[@"type"];
//    NSInteger num = [UIApplication sharedApplication].applicationIconBadgeNumber;
//    num++;
    
//    if (type.integerValue == 2) {
    KDTabBarController *tabbar = (KDTabBarController *)self.window.rootViewController;
    KDNavigationController *nav = tabbar.viewControllers[2];
    KDsubscribController *sub = (KDsubscribController *)nav.topViewController;
    [tabbar setSelectedIndex:2];
    sub.type = type;

    //发送通知给订阅界面
    [[NSNotificationCenter defaultCenter] postNotificationName:@"KDSubscribGetPushNoty" object:nil userInfo:@{@"type":type}];
//    }
    NSNumber *contentid =  userInfo[@"content-id"];
    if (contentid) {
//        UILabel *label = [[UILabel alloc] init];
//        label.frame = CGRectMake(0, 250, 200, 200);
//        label.numberOfLines = 0;
//        label.textColor = [UIColor whiteColor];
//        label.text = [NSString stringWithFormat:@"%@", contentid];
//        label.font = [UIFont systemFontOfSize:30];
//        label.backgroundColor = [UIColor grayColor];
//        [self.window.rootViewController.view addSubview:label];
        //注意: 在此方法中一定要调用这个调用block, 告诉系统是否处理成功.
        // 以便于系统在后台更新UI等操作
        completionHandler(UIBackgroundFetchResultNewData);
        
    }else
    {
        completionHandler(UIBackgroundFetchResultFailed);
    }
    
}

#pragma mark -Shadowsocks配置区
- (void)setVpnWithHost:(NSString *)host port:(NSInteger)port password:(NSString *)passoword method:(NSString *)method{
    proxy = [[ShadowsocksClient alloc] initWithHost:host//@"106.75.199.238"
                                               port:port//8080
                                           password:passoword//@"nicko"
                                             method:@"aes-256-cfb"];
    [proxy startWithLocalPort:8080];
    [SSProxyProtocol setLocalPort:8080];
    [NSURLProtocol registerClass:[SSProxyProtocol class]];
    //如果链接上了，就开启定时器循环！
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            ///定时每隔4分钟发送一次数据给服务器检测心跳
        if ([_timer isValid]) {
            
            [_timer invalidate];
            _timer=nil;
        }
            _timer = [NSTimer scheduledTimerWithTimeInterval:4*60 target:self selector:@selector(aliveVpnOnlineStatus) userInfo:nil repeats:YES];
            //放到子线程
            [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
        
    });
    
}

- (void)aliveVpnOnlineStatus{
    KDVpnOnlineStatusParam *param = [[KDVpnOnlineStatusParam alloc]init];
    KDAccount *account = [KDAccountTool account];
    param.gid = account.gid;
    param.userId = account.userId;
    param.ip = proxy.host;
    [KDGetVpnServiceTool aliveVpnOnlineStatusWithParam:param success:^(KDStatusResult *responseObejct) {
        KDLog(@"%@",responseObejct.msg);
        if ([responseObejct.msg isEqualToString:@"操作成功" ])  {
            
        }
    } failure:^(NSError *error) {
        KDLog(@"%@",error);
    }];
}
- (void)CloseTimer:(NSNotification *)noty{
    //将之前的代理关掉
    if (proxy) {
        [proxy stop];
        proxy = nil;
    }
    if ([_timer isValid]) {
        
        [_timer invalidate];
        _timer=nil;
    }
}
- (void)getVpnModel:(NSNotification *)noty{
    KDVpnModel *model =  noty.userInfo[@"KDVpnModel"];
    [self setVpnWithHost:model.server port:model.port password:model.pwd method:model.encryption];
}
//被重置了
- (void)VPNConectFail:(NSNotification *)noty{
    KDLog(@"proxy.isConnected:%d",proxy.isConnected);

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [SVProgressHUD showWithStatus:@"vpn服务器失效，自动切换服务器中..." maskType:SVProgressHUDMaskTypeGradient];
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [SVProgressHUD showSuccessWithStatus:@"切换成功！" maskType:SVProgressHUDMaskTypeGradient];
        });

    });

    if (proxy) {
        [proxy stop];
        proxy = nil;
    }
    [KDGetVpnServiceTool getVpnModel];
}
- (void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
//定时去服务器取通知
-(void)noticeTimeInterval{
    //如果链接上了，就开启定时器循环！
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        ///定时每隔10秒分钟发送一次数据给服务器检测心跳
        if ([_timer_message_push isValid]) {
            
            [_timer_message_push invalidate];
            _timer_message_push=nil;
        }
        _timer_message_push = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(getNoticeList) userInfo:nil repeats:YES];
        //放到子线程
        [[NSRunLoop mainRunLoop] addTimer:_timer_message_push forMode:NSRunLoopCommonModes];
        
    });

}

//获取通知列表
- (void)getNoticeList{
    
    KDAccount *account = [KDAccountTool account];
    [KDMessagePushRequestTool getNoticeList:^(KDBaseResult *responseObj) {
        
        if([responseObj.code isEqualToString:@"1"]){
            
            KDNoticeListMiddleBaseResult * middleResult= [KDNoticeListMiddleBaseResult objectWithKeyValues:responseObj.data];
            NSString *ss=middleResult.news;
            if(middleResult!=nil){
                NSArray *newsContent= middleResult.newsContent;
              
                if(newsContent!=nil){
                    
                    for (NSInteger i=0; i<newsContent.count; i++) {
                        KDNoticeListBaseResult *baseResult= newsContent[i];
                        NSString *pushType= baseResult.pushType;
                        KDMessagePushListCellModel *model= baseResult.content;
                        if([pushType isEqualToString:@"2"] && model!=nil){
                           [self createLocalizedUserNotification:model];
                        }
                       
                    }
                }
            }
        }
        
    } failure:^(NSError *error) {
        KDLog(@"%@",error);
        
    }];
    
    
    
   
    
}
//创建通知
- (void)createLocalizedUserNotification:(KDMessagePushListCellModel *) content{
    //- (void)createLocalizedUserNotification{
    // 1.创建本地通知
    UILocalNotification *localNote = [[UILocalNotification alloc] init];
    
    // 2.设置本地通知的内容
    // 2.1.设置通知发出的时间
    localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:3.0];
    // 2.2.设置通知的内容
    //localNote.alertBody = @"在干吗?";
    localNote.alertBody = [NSString filterHTML:content.crawTitle];
    // 2.3.设置滑块的文字（锁屏状态下：滑动来“解锁”）
    localNote.alertAction = @"解锁";
    // 2.4.决定alertAction是否生效
    localNote.hasAction = NO;
    // 2.5.设置点击通知的启动图片
    //localNote.alertLaunchImage = @"123Abc";
    // 2.6.设置alertTitle
    //localNote.alertTitle = @"你有一条新通知";
    // 2.7.设置有通知时的音效
    //localNote.soundName = @"buyao.wav";
    // 2.8.设置应用程序图标右上角的数字
    // localNote.applicationIconBadgeNumber = 999;
    
    // 2.9.设置额外信息
    localNote.userInfo = @{@"newsId" : content.newsId};
    
    // 3.调用通知
    [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
    
    
}

/**
 app在前台收到本地通知调用或者在home情况下点击通知进入前台调用
 */

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    NSLog(@"收到本地通知");
    
    // 可以让用户跳转到指定界面 app在前台接收到通知直接跳转界面不太好,所以要判断一下,是从后台进入前台还是本身就在前台
    if (application.applicationState == UIApplicationStateInactive) {// 进入前台时候
        NSLog(@"跳转到指定界面");
        
        // 如果接收到不同的通知,跳转到不同的界面:
        NSLog(@"%@", notification.userInfo); //通知的额外信息,根据设置的通知的额外信息确定
        
        NSString *newsId = notification.userInfo[@"newsId"];
        [self getNewsModelWithID:newsId success:^(KDSubscribCellModel *model) {
            
            
            singleCtrl = [[KDDetailSubscribController alloc]init];
            singleCtrl.model = model;
            
            
            
            KDTabBarController *tabbar = (KDTabBarController *)self.window.rootViewController;
            // NSInteger sss= tabbar.viewControllers.count;
            
            KDNavigationController *nav = tabbar.viewControllers[0];
            
            
            if(![nav.topViewController isKindOfClass:[singleCtrl class]]) {
                
                [nav pushViewController:singleCtrl animated:YES];
            }
            
        }];
        
        
    }
}

/**
 *  通过ID，请求获取一个本信息的所有细节
 *
 *  @param ID 信息ID
 */
- (void)getNewsModelWithID:(NSString *)ID success:(void (^)(KDSubscribCellModel *model))success{
    
    KDMoveFavorParam *param = [[KDMoveFavorParam alloc]init];
    param.ID = ID;
    [SVProgressHUD showWithStatus:@"加载中…" maskType:SVProgressHUDMaskTypeGradient];
    [KDCollectRequestTool getNewsWithParam:param success:^(KDBaseResult *responseObejct) {
        if ([responseObejct.code isEqualToString:@"1"]) {
            KDSubscribCellModel * model= [KDSubscribCellModel objectWithKeyValues:responseObejct.data];
            [SVProgressHUD dismiss];
            if (model) {
                success(model);
            }else{
                [SVProgressHUD showInfoWithStatus:@"未查询到数据" maskType:SVProgressHUDMaskTypeGradient];
            }
            
        }else{
            [SVProgressHUD showErrorWithStatus:responseObejct.msg maskType:SVProgressHUDMaskTypeGradient];
        }
    } failure:^(NSError *error) {
        [SVProgressHUD showErrorWithStatus:@"网络错误!" maskType:SVProgressHUDMaskTypeGradient];
    }];
}


@end
